#include <bits/stdc++.h>
using namespace std;

/*
题目描述：
有一个 H×W 的棋盘格，每个格子要么是空的，要么是障碍物。
给定一个起点和一个终点，要求从起点到终点的最少步数。
移动规则：必须水平移动和垂直移动交替进行（水平→垂直→水平→垂直...），
第一次移动可以是水平或垂直。

解题思路：
使用BFS（广度优先搜索）算法。
状态定义：(x, y, last_direction)，其中last_direction表示上一步的移动方向
         0表示水平移动，1表示垂直移动
对于每个状态，我们记录到达该状态所需的最小步数。
*/

#define MAXN 1024

// 检查坐标是否有效的辅助函数
bool isValid(int x, int y, int h, int w) {
  return x >= 1 && x <= h && y >= 1 && y <= w;
}

int h, w;
bool is_obstacle[MAXN][MAXN];       // 障碍物标记数组
int start_x, start_y, end_x, end_y; // 起点和终点坐标

// BFS状态结构体
struct State {
  int x, y;           // 当前位置坐标
  int last_direction; // 上一步的移动方向：0-水平，1-垂直
  int steps;          // 已走步数
};

// 访问标记数组：vis[x][y][direction] 表示以direction方向到达(x,y)是否已访问
bool visited[MAXN][MAXN][2];

// 广度优先搜索求解最短路径
int bfs() {
  queue<State> q;

  // 初始状态：从起点出发，可以是水平或垂直移动
  q.push({start_x, start_y, 0, 0}); // 初始为水平移动
  q.push({start_x, start_y, 1, 0}); // 初始为垂直移动
  visited[start_x][start_y][0] = true;
  visited[start_x][start_y][1] = true;

  while (!q.empty()) {
    State current = q.front();
    q.pop();

    // 如果到达终点，返回步数
    if (current.x == end_x && current.y == end_y) {
      return current.steps;
    }

    // 根据上一步的方向决定本次移动方向
    // 如果上一步是水平移动，则本次必须垂直移动
    // 如果上一步是垂直移动，则本次必须水平移动
    for (int delta = -1; delta <= 1; delta += 2) { // delta为-1或1，表示移动方向
      State next = current;

      if (current.last_direction == 0) {
        // 上一步是水平移动，现在应该垂直移动
        next.x += delta;
      } else {
        // 上一步是垂直移动，现在应该水平移动
        next.y += delta;
      }

      // 更新状态
      next.last_direction ^= 1; // 切换方向：0变1，1变0
      next.steps++;             // 步数增加

      // 检查新位置是否有效
      if (!isValid(next.x, next.y, h, w))
        continue;
      if (is_obstacle[next.x][next.y])
        continue;
      if (visited[next.x][next.y][next.last_direction])
        continue;

      // 标记为已访问并加入队列
      visited[next.x][next.y][next.last_direction] = true;
      q.push(next);
    }
  }

  // 无法到达终点
  return -1;
}

int main() {
  // 读取棋盘尺寸
  cin >> h >> w;

  // 读取棋盘信息
  for (int i = 1; i <= h; ++i) {
    string row;
    cin >> row;
    row = " " + row; // 使索引从1开始对齐

    for (int j = 1; j <= w; ++j) {
      char cell = row[j];

      if (cell == 'S') {
        // 起点
        start_x = i;
        start_y = j;
      } else if (cell == 'G') {
        // 终点
        end_x = i;
        end_y = j;
      } else if (cell == '#') {
        // 障碍物
        is_obstacle[i][j] = true;
      }
    }
  }

  // 执行BFS搜索并输出结果
  int result = bfs();
  cout << result << endl;

  return 0;
}